<?php

namespace app\common\services;

use lib\redis\RedisCache;

class RedisService
{
    /**
     * @var \Redis
     */
    protected $redis;

    public function __construct(int $conId,array $configs)
    {
        $this->redis = RedisCache::instance($conId,$configs);
    }

    /**
     * 设置redis数据
     * @param string $key
     * @param array $data
     * @param int $expire
     * @return bool|\Redis
     * @Function:setBucket
     * @Date: 2022/11/8
     * @Time: 18:04
     */
    public function setBucket(string $key, array $data = [], int $expire = 2592000)
    {
        try {
            if ($this->getBucket($key)) $this->removeBucket($key);
            return $this->redis->set($key , json_encode($data, JSON_UNESCAPED_UNICODE), $expire);
        } catch (\Throwable $e) {
            return false;
        }
    }
    public function setData(string $key,$data, $expire = 2592000)
    {
        try {
            $data = is_array($data) ? json_encode($data) : $data;
            if ($this->getBucket($key)) $this->removeBucket($key);
            return $this->redis->set($key , json_encode($data, JSON_UNESCAPED_UNICODE), $expire);
        } catch (\Throwable $e) {
            return false;
        }
    }

    /**
     * 移除redis数据
     * @param string $key
     * @return false|int|\Redis
     * @Function:removeBucket
     * @Date: 2022/11/8
     * @Time: 18:04
     */
    public function removeBucket(string $key)
    {
        try {
            return $this->redis->del($key);
        } catch (\Throwable $e) {
            return false;
        }
    }

    /**
     * 获取redis数据
     * @param string $key
     * @return false|mixed|\Redis|string
     * @Function:getBucket
     * @Date: 2022/11/8
     * @Time: 18:04
     */
    public function getBucket(string $key)
    {
        try {
            return json_decode($this->redis->get($key), true);
        } catch (\Throwable $e) {
            return false;
        }
    }

    /**
     * 设置redis集合
     * @param string $key
     * @param array $data
     * @param $expire
     * @return bool|\Redis
     * @Function:sAddBucket
     * @Date: 2022/11/12
     * @Time: 10:39
     */
    public function sAddBucket(string $key, $data = array(), $expire = 2592000)
    {
        try {
/*            $gAddData  = $this->gAddBucket($key);
            $setStatus = array_column($gAddData, 'user_id', 'user_id');
            foreach ($gAddData as $item)
            {
                if ($setStatus[$item['user_id']] == $item['user_id'])
                {
                    $this->sRemBucket($key, json_encode($item));
                }
            }*/
            $this->redis->sAdd($key , json_encode($data, JSON_UNESCAPED_UNICODE));
            $this->redis->expire($key, $expire);
            return true;
        } catch (\Throwable $e) {
            return false;
        }
    }

    /**
     * 获取redis集合
     * @param string $key
     * @return false|\think\Collection
     * @Function:gAddBucket
     * @Date: 2022/11/12
     * @Time: 11:21
     */
    public function gAddBucket(string $key)
    {
        try {
            $data = $this->redis->sMembers($key);
            return collect($data)->map(function ($item) {
                return json_decode($item, true);
            })->toArray();
        } catch (\Throwable $e) {
            return false;
        }
    }

    public function gScardBucket(string $key)
    {
        try {
            return $this->redis->sCard($key);
        } catch (\Throwable $e) {
            return false;
        }
    }

    public function sRemBucket(string $key, $row)
    {
        try {
            return $this->redis->sRem($key, $row);
        } catch (\Throwable $e) {
            return false;
        }
    }

    public function setIncrbyBucket(string $key, int $value = 1, $expire = 604800)
    {
        try {
            $this->redis->incrBy($key, $value);
            $this->redis->expire($key, $expire);
            return true;
        } catch (\Throwable $e) {
            return false;
        }
    }

    public function setDecrByBucket(string $key, $value = 1, $expire = 604800)
    {
        try {
            $this->redis->decrBy($key, $value);
            $this->redis->expire($key, $expire);
            return true;
        } catch (\Throwable $e) {
            return false;
        }
    }

    public function setLpushBucket(string $key, $data = array(), $expire = 604800)
    {
        try {
            $this->redis->lPush($key, json_encode($data, JSON_UNESCAPED_UNICODE));
            $this->redis->expire($key, $expire);
            return true;
        } catch (\Throwable $e) {
            return false;
        }
    }

    public function setLsetBucket($key, $index, $data = array(), $expire = 604800)
    {
        try {
            $this->redis->lSet($key, $index, json_encode($data, JSON_UNESCAPED_UNICODE));
            $this->redis->expire($key, $expire);
            return true;
        } catch (\Throwable $e) {
            return false;
        }
    }

    public function getLindexBucket($key, $index = 0)
    {
        try {
            return $this->redis->lIndex($key, $index);
        } catch (\Throwable $e) {
            return false;
        }
    }

    public function getRPopBucket(string $key)
    {
        try {
            return $this->redis->rPop($key);
        } catch (\Throwable $e) {
            return false;
        }
    }

    public function getLPopBucket(string $key)
    {
        try {
            $data = $this->redis->lPop($key);
            return !empty($data) ? json_decode($data, true) : [];
        } catch (\Throwable $e) {
            return false;
        }
    }

    public function getLrangeBucket(string $key, int $start = 0, int $end = 0)
    {
        try {
            $end = ($end > 0) ? $end : $this->getLitsLen($key);
            $data = $this->redis->lRange($key, $start, $end);
            return collect($data)->map(function ($item) {
                return json_decode($item, true);
            })->toArray();
        } catch (\Throwable $e) {
            return false;
        }
    }
    
    public function Lrem(string $key, $value){
		try {
			$value=is_array($value)?json_encode($value,JSON_UNESCAPED_UNICODE):$value;
			return $this->redis->lRem($key,$value,-1);
		} catch (\Throwable $e) {
			return false;
		}
	}
	
	public function hDel($key,$hashKey){
		return $this->redis->hDel($key, $hashKey);
	}

    public function getLitsLen(string $key)
    {
        try {
            return $this->redis->Llen($key);
        } catch (\Throwable $e) {
            return false;
        }
    }

    /**
     * 有序集合
     * @param $key
     * @param $index
     * @param $score
     * @return bool
     * @Function:zadd
     * @Date: 2022/12/6
     * @Time: 20:36
     */
    public function zAddBucket($key, $index ,$score)
    {
        try {
            $this->redis->zAdd($key, $score, $index);
            return true;
        } catch (\Throwable $e) {
            return false;
        }
    }

    public function setZScoreBucket(string $key, $value)
    {
        try {
            return $this->redis->zScore($key, $value);
        } catch (\Throwable $e) {
            return false;
        }
    }

    public function zcard($key)
    {
        try {
            return $this->redis->zCard($key);
        } catch (\Throwable $e) {
            return false;
        }
    }

    public function zIncrBy($key, $index, $score = 1)
    {
        try {
            return $this->redis->zIncrBy($key , $score , $index);
        } catch (\Throwable $e) {
            return false;
        }
    }

    public function zRevRange($key, $start, $end)
    {
        try {
            return $this->redis->zRevRange($key, $start, $end,true);
        } catch (\Throwable $e) {
            return false;
        }
    }
	
	//批量获取数据
	public function batchMget($keys){
		$lists= $this->redis->mget($keys);
		foreach ($lists as $k=>$list){
			$lists[$k]=isJson($list)?json_decode($list,true):$list;
		}
		return $lists;
	}
}
